package com.flute.framework.index.analysis;

import java.io.IOException;
import java.io.Reader;

import org.apache.lucene.analysis.Tokenizer;
import org.apache.lucene.analysis.tokenattributes.PayloadAttribute;
import org.apache.lucene.analysis.tokenattributes.TermAttribute;
import org.apache.lucene.index.Payload;
import org.apache.lucene.util.AttributeSource;

import com.flute.framework.index.fieldbuilder.ScoreField;

public class PayloadTokenizer extends Tokenizer {

	private int position;
	private ScoreField scoreField;
	private TermAttribute termAtt;
	private PayloadAttribute payAtt;

	public PayloadTokenizer(ScoreField scoredString) {
		this.scoreField = scoredString;
		this.position = 0;
		termAtt = addAttribute(TermAttribute.class);
		payAtt = addAttribute(PayloadAttribute.class);
	}

	public PayloadTokenizer(Reader input) {
		super(input);
		this.position = 0;
		termAtt = addAttribute(TermAttribute.class);
		payAtt = addAttribute(PayloadAttribute.class);
	}

	public PayloadTokenizer(AttributeSource source, Reader input) {
		super(source, input);
		this.position = 0;
		termAtt = addAttribute(TermAttribute.class);
		payAtt = addAttribute(PayloadAttribute.class);
	}

	public PayloadTokenizer(AttributeFactory factory, Reader input) {
		super(factory, input);
		this.position = 0;
		termAtt = addAttribute(TermAttribute.class);
		payAtt = addAttribute(PayloadAttribute.class);
	}

	@Override
	public final boolean incrementToken() throws IOException {
		clearAttributes();
		if (position < scoreField.size()) {
			String term = scoreField.getString(position);
			termAtt.setTermBuffer(term);
			payAtt
					.setPayload(new Payload(scoreField.getScores(term)
							.toBytes()));
			// payAtt.setPayload(new Payload(new byte[10]));
			position++;
			return true;
		} else {
			return false;
		}
	}

	@Override
	public final void end() {
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result + ((payAtt == null) ? 0 : payAtt.hashCode());
		result = prime * result + position;
		result = prime * result
				+ ((scoreField == null) ? 0 : scoreField.hashCode());
		result = prime * result + ((termAtt == null) ? 0 : termAtt.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if(!super.equals(obj)){
			return Boolean.FALSE;
		}
		if (this == obj)
			return Boolean.TRUE;
		if (!super.equals(obj))
			return Boolean.FALSE;
		if (!(obj instanceof PayloadTokenizer))
			return Boolean.FALSE;
		PayloadTokenizer other = (PayloadTokenizer) obj;
		if (payAtt == null) {
			if (other.payAtt != null)
				return Boolean.FALSE;
		} else if (!payAtt.equals(other.payAtt))
			return Boolean.FALSE;
		if (position != other.position)
			return Boolean.FALSE;
		if (scoreField == null) {
			if (other.scoreField != null)
				return Boolean.FALSE;
		} else if (!scoreField.equals(other.scoreField))
			return Boolean.FALSE;
		if (termAtt == null) {
			if (other.termAtt != null)
				return Boolean.FALSE;
		} else if (!termAtt.equals(other.termAtt))
			return Boolean.FALSE;
		return Boolean.TRUE;
	}

	@Override
	public void reset(Reader input) throws IOException {
		super.reset(input);
		this.position = 0;
	}

	public ScoreField getScoreField() {
		return scoreField;
	}

	public void setScoreField(ScoreField scoreField) {
		this.scoreField = scoreField;
	}
}
